/*********************************************************************************/
/*                                                                               */
/*      WDG Driver                                                               */
/*                                                                               */
/*      Last updated by:   CBS                                                   */
/*      Last update date:  2013/2/8                                              */
/*      Revision:          0                                                     */
/*      Copyright:         DENSO                                                 */
/*                                                                               */
/*********************************************************************************/

/*********************************************************************************/
/*  include files                                                                */
/*********************************************************************************/
#include "MPC5674F_MVx264.h"
#include "WdgSwt.h"
#include "Wdg_SwtCbk.h"
#include "Gpt.h"

/*********************************************************************************/
/*  prototypes                                                                   */
/*********************************************************************************/
static Std_ReturnType Wdg_CheckInit(const Wdg_ConfigType* ConfigPtr);
static Std_ReturnType Wdg_CheckSetMode(WdgIf_ModeType Mode);
static Std_ReturnType Wdg_CheckSetTriggerContidion(U2 timeout);
static Std_ReturnType Wdg_CheckGetVersionInfo(Std_VersionInfoType* versioninfo);
void Det_ReportError(U2 a, U1 b, U1 c, U1 d);

/*********************************************************************************/
/*  defines / data types / structs / unions / macros                             */
/*********************************************************************************/
#define Irq_Disable() 	asm volatile (" wrteei 0")
#define Irq_Enable() 	asm volatile (" wrteei 1")

/*********************************************************************************/
/*  constants                                                                    */
/*********************************************************************************/
/* Pointer to configuration structure */
static const Wdg_ConfigType *WdgConfigPtr;

/*********************************************************************************/
/*  variables                                                                    */
/*********************************************************************************/
typedef enum
{
    WDG_UNINIT,
    WDG_IDLE,
    WDG_BUSY
}Wdg_StateType;

#if (WDG_VERSION_INFO_API == STD_ON)
static Std_VersionInfoType WDG_VersionInfo =
{
    WDG_VENDOR_ID, 
    MODULE_ID_WDG,
    WDG_INSTANCE_ID,
    WDG_SW_MAJOR_VERSION,
    WDG_SW_MINOR_VERSION,
    WDG_SW_PATCH_VERSION,
    WDG_AR_MAJOR_VERSION,
    WDG_AR_MINOR_VERSION,
    WDG_AR_PATCH_VERSION 
};
#endif  /* WDG_VERSION_INFO_API */

static Wdg_StateType wdgState = WDG_UNINIT;

/*********************************************************************************/
/*  API Functions                                                                */
/*********************************************************************************/

/***************************************************************************************************/
/*  Service name    :   Wdg_Init                                                                   */
/*  Sync/Async      :   Synchronous                                                                */
/*  Reentrancy      :   Non Reentrant                                                              */
/*  Parameters (in) :   Pointer to configuration set.                                              */
/*  Return value    :   None                                                                       */
/*  Discription     :   Initialize the module.                                                     */
/***************************************************************************************************/
void Wdg_Init(const Wdg_ConfigType* ConfigPtr)
{
    if(E_OK == Wdg_CheckInit(ConfigPtr))
    {
        WdgConfigPtr = ConfigPtr;

        if(WdgConfigPtr->DefaultMode == WDGIF_OFF_MODE)
        {
            if(WdgConfigPtr->ServiceMode == WDG_FIXED_SERVICE_MODE)
            {
                SWT.MCR.B.KEY = 0;
            }
            else  /* WDG_KEYED_SERVICE_MODE */
            {
                SWT.MCR.B.KEY = 1;
            }

            SWT.MCR.B.CSL = 0;  /* System clock */

            SWT.MCR.B.WEN = 0;
        }
        else if(WdgConfigPtr->DefaultMode == WDGIF_SLOW_MODE)
        {
            if(WdgConfigPtr->ServiceMode == WDG_FIXED_SERVICE_MODE)
            {
                SWT.MCR.B.KEY = 0;
            }
            else  /* WDG_KEYED_SERVICE_MODE */
            {
                SWT.MCR.B.KEY = 1;
            }

            SWT.MCR.B.CSL = 0;  /* System clock */

            Irq_Disable();
            Gpt_StartTimer(WdgConfigPtr->GptChannel,(WdgConfigPtr->SettingsSlow->TimeServiceWatchDog) * WDG_SYSTEM_CLOCK / 1000);
            SWT.TO.R = (WdgConfigPtr->SettingsSlow->TimeOut) * WDG_SYSTEM_CLOCK / 1000;
            SWT.MCR.B.WEN = 1;
            Irq_Enable();
        }
        else  /* WDGIF_FAST_MODE */
        {
            if(WdgConfigPtr->ServiceMode == WDG_FIXED_SERVICE_MODE)
            {
                SWT.MCR.B.KEY = 0;
            }
            else  /* WDG_KEYED_SERVICE_MODE */
            {
                SWT.MCR.B.KEY = 1;
            }

            SWT.MCR.B.CSL = 0;  /* System clock */

            Irq_Disable();
            Gpt_StartTimer(WdgConfigPtr->GptChannel,(WdgConfigPtr->SettingsFast->TimeServiceWatchDog) * WDG_SYSTEM_CLOCK / 1000);
            SWT.TO.R = (WdgConfigPtr->SettingsFast->TimeOut) * WDG_SYSTEM_CLOCK / 1000;
            SWT.MCR.B.WEN = 1;
            Irq_Enable();
        }
        wdgState = WDG_IDLE;
    }
}

/***************************************************************************************************/
/*  Service name    :   Wdg_SetMode                                                                */
/*  Sync/Async      :   Synchronous                                                                */
/*  Reentrancy      :   Non Reentrant                                                              */
/*  Parameters (in) :   WdgIf_ModeType    Mode                                                     */
/*  Return value    :   Std_ReturnTpye    E_OK: command has been accepted.                         */
/*                                        E_NOT_OK: command has not been accepted.                 */
/*  Discription     :   Switch the watchdog into the statically configured mode.                   */
/***************************************************************************************************/
Std_ReturnType Wdg_SetMode(WdgIf_ModeType Mode)
{
    Std_ReturnType returnValue;

    if(E_OK == Wdg_CheckSetMode(Mode))
    {
        wdgState = WDG_BUSY;

        if(Mode == WDGIF_OFF_MODE)
        {
            SWT.MCR.B.WEN = 0;
            Gpt_StopTimer(WdgConfigPtr->GptChannel);
            returnValue = E_OK;
        }
        else if(Mode == WDGIF_SLOW_MODE)
        {
            Irq_Disable();
            SWT.MCR.B.WEN = 0;
            Gpt_StopTimer(WdgConfigPtr->GptChannel);
            Gpt_StartTimer(WdgConfigPtr->GptChannel,(WdgConfigPtr->SettingsSlow->TimeServiceWatchDog) * WDG_SYSTEM_CLOCK / 1000);
            SWT.TO.R = (WdgConfigPtr->SettingsSlow->TimeOut) * WDG_SYSTEM_CLOCK / 1000;
            SWT.MCR.B.WEN = 1;
            Irq_Enable();
            returnValue = E_OK;
        }
        else if(Mode == WDGIF_FAST_MODE)
        {
            Irq_Disable();
            SWT.MCR.B.WEN = 0;
            Gpt_StopTimer(WdgConfigPtr->GptChannel);
            Gpt_StartTimer(WdgConfigPtr->GptChannel,(WdgConfigPtr->SettingsFast->TimeServiceWatchDog) * WDG_SYSTEM_CLOCK / 1000);
            SWT.TO.R = (WdgConfigPtr->SettingsFast->TimeOut) * WDG_SYSTEM_CLOCK / 1000;
            SWT.MCR.B.WEN = 1;
            Irq_Enable();
            returnValue = E_OK;
        }
        else
        {
            returnValue = E_NOT_OK;
        }

        wdgState = WDG_IDLE;
    }
    else
    {
        returnValue = E_NOT_OK;
    }
    return(returnValue);
}

/***************************************************************************************************/
/*  Service name    :   Wdg_SetTriggerCondition                                                    */
/*  Sync/Async      :   Synchronous                                                                */
/*  Reentrancy      :   Non Reentrant                                                              */
/*  Parameters (in) :   U2 timeout:Timeout value(milliseconds) for setting the trigger counter.*/
/*  Return value    :   None                                                                       */
/*  Discription     :   Switch the watchdog into the statically configured mode.                   */
/***************************************************************************************************/
void Wdg_SetTriggerContidion(U2 timeout)
{
    if(E_OK == Wdg_CheckSetTriggerContidion(timeout))
    {
        if((SWT.MCR.B.HLK == 0)&&(SWT.MCR.B.SLK == 0))
        {
            SWT.TO.R = (timeout * WDG_SYSTEM_CLOCK / 1000);
        }
    }
}

/********************************************************************************************************/
/*  Service name    :   Wdg_GetVersionInfo                                                              */
/*  Sync/Async      :   Synchronous                                                                     */
/*  Reentrancy      :   Reentrant                                                                       */
/*  Parameters (in) :   versioninfo   Pointer to where to store the version information of this module. */
/*  Return value    :   None                                                                            */
/*  Discription     :   Return the version information of this module.                                  */
/********************************************************************************************************/
#if(WDG_VERSION_INFO_API == STD_ON)  /* WDG068 */
void Wdg_GetVersionInfo(Std_VersionInfoType* versioninfo)
{
    if(E_OK == Wdg_CheckGetVersionInfo(versioninfo))
    {
        versioninfo->vendorID = WDG_VersionInfo.vendorID;
        versioninfo->moduleID = WDG_VersionInfo.moduleID;
        versioninfo->instanceID = WDG_VersionInfo.instanceID;

        versioninfo->sw_major_version = WDG_VersionInfo.sw_major_version;
        versioninfo->sw_minor_version = WDG_VersionInfo.sw_minor_version;
        versioninfo->sw_patch_version = WDG_VersionInfo.sw_patch_version;

        versioninfo->ar_major_version = WDG_VersionInfo.ar_major_version;
        versioninfo->ar_minor_version = WDG_VersionInfo.ar_minor_version;
        versioninfo->ar_patch_version = WDG_VersionInfo.ar_patch_version;
    }
}
#endif  /* WDG_VERSION_INFO_API */

/*********************************************************************************/
/*    Local Functions                                                            */
/*********************************************************************************/
static Std_ReturnType Wdg_CheckInit(const Wdg_ConfigType* ConfigPtr)
{
    Std_ReturnType returnValue;

#if(WDG_DEV_ERROR_DETECT == STD_ON)
    if(ConfigPtr == (Wdg_ConfigType*)0)
    {
        /* WDG089 */
        Det_ReportError(MODULE_ID_WDG,WDG_INSTANCE_ID, WDG_INIT_SERVICE_ID,WDG_E_PARAM_POINTER);
        returnValue = E_NOT_OK;
    }
    else if(!(wdgState == WDG_UNINIT))
    {
        /* WDG019 */
        Det_ReportError(MODULE_ID_WDG,WDG_INSTANCE_ID,WDG_INIT_SERVICE_ID,WDG_E_DRIVER_STATE);
        returnValue = E_NOT_OK;
    }
    else if(!(ConfigPtr->SettingsSlow->TimeServiceWatchDog < ConfigPtr->SettingsSlow->TimeOut))
    {
        /* WDG090 */
        Det_ReportError(MODULE_ID_WDG,WDG_INSTANCE_ID,WDG_INIT_SERVICE_ID,WDG_E_PARAM_CONFIG);
        returnValue = E_NOT_OK;
    }
    else if(!(ConfigPtr->SettingsFast->TimeServiceWatchDog < ConfigPtr->SettingsFast->TimeOut))
    {
        /* WDG090 */
        Det_ReportError(MODULE_ID_WDG,WDG_INSTANCE_ID,WDG_INIT_SERVICE_ID,WDG_E_PARAM_CONFIG);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* WDG_DEV_ERROR_DETECT */
    return(returnValue);
}

static Std_ReturnType Wdg_CheckSetMode(WdgIf_ModeType Mode)
{
    Std_ReturnType returnValue;

#if(WDG_DEV_ERROR_DETECT == STD_ON)
    if(!(Mode < WDGIF_NBR_OF_MODE))
    {
        /* WDG091 */
        Det_ReportError(MODULE_ID_WDG,WDG_INSTANCE_ID,WDG_SETMODE_SERVICE_ID,WDG_E_PARAM_MODE);
        returnValue = E_NOT_OK;
    }
    else if(!(wdgState == WDG_IDLE))
    {
        /* WDG017 */
        Det_ReportError(MODULE_ID_WDG,WDG_INSTANCE_ID,WDG_SETMODE_SERVICE_ID,WDG_E_DRIVER_STATE);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* WDG_DEV_ERROR_DETECT */
    return(returnValue);
}

static Std_ReturnType Wdg_CheckSetTriggerContidion(U2 timeout)
{
    Std_ReturnType returnValue;

#if(WDG_DEV_ERROR_DETECT == STD_ON)
    if(!(timeout < (WDG_MAX_TIMEOUT * 1000)))
    {
        /* WDG146 */
        Det_ReportError(MODULE_ID_WDG, WDG_INSTANCE_ID,WDG_SETTRIGGERCONDITION_SERVICE_ID,WDG_E_PARAM_TIMEOUT);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* WDG_DEV_ERROR_DETECT */
    return(returnValue);
}

#if(WDG_VERSION_INFO_API == STD_ON)  /* WDG068 */
static Std_ReturnType Wdg_CheckGetVersionInfo(Std_VersionInfoType* versioninfo)
{
    Std_ReturnType returnValue;

#if( WDG_DEV_ERROR_DETECT == STD_ON )
    if( 0 == versioninfo)
    {
        /* WDG174 */
        Det_ReportError(MODULE_ID_WDG,WDG_INSTANCE_ID,WDG_GETVERSIONINFO_SERVICE_ID,WDG_E_PARAM_POINTER);
        returnValue = E_NOT_OK;
    }
    else
    {
        returnValue = E_OK;
    }
#else
    returnValue = E_OK;
#endif  /* WDG_DEV_ERROR_DETECT */
    return(returnValue);
}
#endif  /* WDG_VERSION_INFO_API */

void Det_ReportError(U2 a, U1 b, U1 c, U1 d)
{

}

/**** End Of File ****************************************************************/
